home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FUZZY.ZIP / DO_RESER.B < prev    next >
Text File  |  1986-11-30  |  22KB  |  688 lines

  1. -------------------------------------------------------------------------------
  2. --                                                                           --
  3. --  Separate Unit:  Do_reserved -- process reserved predicates for Prover    --
  4. --                                                                           --
  5. --  Author:  Bradley L. Richards                                             --
  6. --                                                                           --
  7. --     Version     Date     Notes . . .                                      --
  8. --    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    --
  9. --       1.0    - - - - -   Never existed.  First version implemented after  --
  10. --                            Parser et al reached version 2.0               --
  11. --       2.0    20 Jun 86   Initial Version                                  --
  12. --       2.05   13 Jul 86   Split into separate spec and package files       --
  13. --       2.1    21 Jul 86   Demonstration version -- initial predicates      --
  14. --                            implemented; initial debugging completed       --
  15. --       2.2    28 Jul 86   Initial operational version -- 20 predicates     --
  16. --                            implemented, plus lots of squashed bugs        --
  17. --       2.3    19 Aug 86   Use AVL trees for rule_base, add many reserved   --
  18. --                            predicates, and split output routines into     --
  19. --                            package print_stuff.                           --
  20. --       2.4    31 Aug 86   Do_reserved split out from Prover                --
  21. --    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    --
  22. --                                                                           --
  23. --  Description:  The procedure Do_reserved accepts Fuzzy Prolog reserved    --
  24. --       predicates from Seek and processes them.  Most predicates have      --
  25. --       their own subprocedure, but a few (e.g. asserta/assertz) are        --
  26. --       combined.  After Do_reserved, all routines appear alphabetically.   --
  27. --                                                                           --
  28. -------------------------------------------------------------------------------
  29.  
  30. separate(prover)
  31. procedure do_reserved( pred, goal_tree : AST_ptr; result_node : out AST_ptr;
  32.             bindings : in out binding_list; level : natural;
  33.                         failed : in out boolean ) is
  34.  
  35.     new_rule, new_rules, temp : AST_ptr;
  36.     template : constant AST_ptr := new AST'(implication,
  37.           new AST'(predicate, null, null), null, null, null);
  38.     a_template : constant argument_ptr := new argument'(float_num, null, 0.0);
  39.     file_ptr, value, value2, read_value : argument_ptr;
  40.     temp_bindings : binding_list;
  41.     int_arg, value_level, value2_level : integer;
  42.     result_done : boolean := false;
  43.     duplicate, not_found, unified : boolean;
  44.     result : float := 0.0;
  45.  
  46.     
  47.     procedure dr_assert is
  48.  
  49.  
  50.         --
  51.         --  Eval -- This set of three routines evalutes arguments.  Eval_args
  52.         --          evalutes the arguments in a functor's argument list, and is
  53.     --          the main routine called by dr_assert.  Eval evaluates a
  54.     --          single argument, and eval_list evaluates the contents of
  55.     --          a prolog list.
  56.         --
  57.         function eval_args( in_args : argument_ptr; bindings : binding_list;
  58.                     level : natural ) return argument_ptr;
  59.  
  60.         function eval_list( in_list : p_list_ptr; bindings : binding_list;
  61.                     level : natural ) return p_list_ptr;
  62.  
  63.         function eval( in_arg : argument_ptr; bindings : binding_list;
  64.                level : natural ) return argument_ptr is
  65.         value : argument_ptr;
  66.         value_level : natural;
  67.           begin
  68.         lookup(in_arg, level, bindings, value, value_level);
  69.         if value.is_a = predicate then
  70.           return new argument'(predicate, null, value.name,
  71.                eval_args(value.p_arguments, bindings, value_level));
  72.         elsif value.is_a = prolog_list then
  73.           return new argument'(prolog_list, null,
  74.                   eval_list(value.list, bindings, value_level));
  75.         else
  76.           return new argument'(value.all);
  77.         end if;
  78.           end eval;
  79.  
  80.         function eval_args( in_args : argument_ptr; bindings : binding_list;
  81.                     level : natural ) return argument_ptr is
  82.         args : argument_ptr := in_args;
  83.         new_arg : argument_ptr := null;
  84.         new_args, temp : argument_ptr;
  85.           begin
  86.         while args /= null loop
  87.           temp := eval(args, bindings, level);
  88.           if new_arg = null then -- this is the first argument
  89.             new_arg := temp;
  90.             new_args := new_arg;
  91.           else
  92.             new_arg.next_arg := temp;
  93.             new_arg := new_arg.next_arg;
  94.           end if;
  95.           new_arg.next_arg := null;
  96.           args := args.next_arg;
  97.         end loop;
  98.         return new_args;
  99.           end eval_args;
  100.  
  101.         function eval_list( in_list : p_list_ptr; bindings : binding_list;
  102.                     level : natural ) return p_list_ptr is
  103.         elts : p_list_ptr := in_list;
  104.         new_elt : p_list_ptr := null;
  105.         new_elts, temp : p_list_ptr;
  106.           begin
  107.         while elts /= null loop
  108.           --
  109.           --  Ada, in its infinite error checking, requires the following
  110.           --  useless if statement in order to keep the discriminate static
  111.           --
  112.           if elts.has_tail then
  113.             temp := new p_list'(true, eval(elts.elt, bindings, level), null);
  114.           else
  115.             temp := new p_list'(false, eval(elts.elt, bindings, level), null);
  116.           end if;
  117.           if new_elt = null then -- this is the first argument
  118.             new_elt := temp;
  119.             new_elts := new_elt;
  120.           else
  121.             new_elt.next_elt := temp;
  122.             new_elt := new_elt.next_elt;
  123.           end if;
  124.           if elts.has_tail then
  125.         new_elt.tail := eval(elts.tail, bindings, level);
  126.         exit;
  127.           else
  128.             elts := elts.next_elt;
  129.           end if;
  130.         end loop;
  131.         return new_elts;
  132.       end eval_list;
  133.  
  134.       begin -- dr_assert
  135.     if (pred.r_arguments = null) then
  136.       error(no_pointer,"ASSERTA/Z called without any arguments");
  137.       failed := true;
  138.     else
  139.       lookup(pred.r_arguments, level, bindings, value, value_level);
  140.       if pred.r_arguments.next_arg = null then -- use default truth of 1.0
  141.         a_template.fp_num := 1.0;
  142.         value2 := a_template;
  143.       else
  144.         lookup(pred.r_arguments.next_arg,level,bindings,value2,value2_level);
  145.       end if;
  146.       if value.is_a /= predicate then
  147.         error(no_pointer, "first argument to ASSERTA/Z must be a functor");
  148.         failed := true;
  149.       elsif (value2.is_a /= float_num) or else (value2.fp_num < 0.0) or else
  150.         (value2.fp_num > 1.0) then
  151.         error(no_pointer,"2nd argument to ASSERTA/Z must be a fuzzy value");
  152.         failed := true;
  153.       else
  154.         new_rule :=
  155.         new AST'(implication,
  156.              new AST'(predicate, value.name,
  157.                  eval_args(value.p_arguments,bindings,value_level)),
  158.              new AST'(fuzzy_value, value2.fp_num), null, null);
  159.         add_node(rule_base, new_rule, duplicate);
  160.         if duplicate then
  161.           temp := fetch_node(rule_base, new_rule);
  162.           if temp = null then
  163.             update_node(rule_base, new_rule, not_found);
  164.         if not_found then
  165.           raise prover_error;
  166.         end if;
  167.           else
  168.             if pred.predicate = rw_asserta then
  169.               new_rule.next := temp;
  170.               temp.prev := new_rule;
  171.               update_node(rule_base, new_rule, not_found);
  172.           if not_found then
  173.             raise prover_error;
  174.           end if;
  175.             else
  176.               while temp.next /= null loop
  177.             temp := temp.next;
  178.               end loop;
  179.               temp.next := new_rule;
  180.               new_rule.prev := temp;
  181.             end if;
  182.           end if;
  183.         end if;
  184.         result := 1.0;
  185.           end if;
  186.     end if;
  187.       end dr_assert;
  188.  
  189.  
  190.     procedure dr_call is
  191.       begin
  192.     if pred.r_arguments = null then
  193.       error(no_pointer,"CALL requires one argument");
  194.       failed := true;
  195.     else
  196.       lookup(pred.r_arguments, level, bindings, value, value_level);
  197.       if (value.is_a /= predicate) then
  198.         error(no_pointer,"argument to CALL must be a functor");
  199.         failed := true;
  200.       else
  201.         result_node :=
  202.         new AST'(resolution_marker, value_level, threshold,
  203.              new AST'(predicate, value.name, value.p_arguments));
  204.         result_done := true;
  205.       end if;
  206.     end if;
  207.       end dr_call;
  208.  
  209.  
  210.     procedure dr_consult is
  211.  
  212.     rule_count : integer;
  213.  
  214.         --
  215.         --  Append -- Used by consult to add rules to rule base.
  216.         --
  217.         procedure append(rule_base : in out tree_ptr; in_rules : AST_ptr;
  218.              rule_count : out integer) is
  219.         duplicate : boolean;
  220.         next_rule, node : AST_ptr;
  221.         new_rules : AST_ptr := in_rules;
  222.         counter : integer := 0;
  223.           begin
  224.         while new_rules /= null loop
  225.           next_rule := new_rules.next;
  226.           new_rules.prev := null;
  227.           new_rules.next := null;
  228.           add_node(rule_base, new_rules, duplicate);
  229.           if duplicate then
  230.             node := fetch_node( rule_base, new_rules );
  231.             if node /= null then
  232.               while node.next /= null loop
  233.                 node := node.next;
  234.               end loop;
  235.               node.next := new_rules;
  236.               new_rules.prev := node;
  237.             else
  238.               raise prover_error;
  239.             end if;
  240.           end if;
  241.           new_rules := next_rule;
  242.           counter := counter + 1;
  243.         end loop;
  244.         rule_count := counter;
  245.           end append;
  246.  
  247.  
  248.       begin -- dr_consult
  249.     file_ptr := pred.r_arguments;
  250.     while file_ptr /= null loop
  251.       if file_ptr.is_a = predicate then
  252.         put(file_ptr.name.name);
  253.         start_parser(file_ptr.name.name, "");
  254.         parse_file(new_rules);
  255.         stop_parser;
  256.         if number_of_errors = 0 then
  257.           append(rule_base, new_rules, rule_count);
  258.           result := 1.0;
  259.           put(" has "); put(rule_count, 1); put(" rules");
  260.         else
  261.           put(file_ptr.name.name & " ignored");
  262.           failed := true;
  263.         end if;
  264.         new_line;
  265.       else
  266.         put_line("invalid file name");
  267.         failed := true;
  268.       end if;
  269.       file_ptr := file_ptr.next_arg;
  270.     end loop;
  271.       end dr_consult;
  272.  
  273.  
  274.     procedure dr_fuzzy is
  275.       begin
  276.     if pred.r_arguments = null then
  277.       error(no_pointer,"FUZZY requires one argument");
  278.       failed := true;
  279.     else
  280.       lookup(pred.r_arguments, level, bindings, value, value_level);
  281.       if value.is_a = float_num then
  282.         if (value.fp_num < 0.0) or (value.fp_num > 1.0) then
  283.           error(no_pointer, "value to FUZZY out of range");
  284.           failed := true;
  285.         else
  286.           result := value.fp_num;
  287.         end if;
  288.       elsif value.is_a = variable then
  289.         a_template.fp_num := current_truth;
  290.         unify_arg(value, a_template, value_level, level, bindings, unified);
  291.         result := current_truth;
  292.         if not unified then
  293.           raise prover_error;
  294.         end if;
  295.       else
  296.         error(no_pointer, "invalid node type to FUZZY");
  297.         failed := true;
  298.       end if;
  299.     end if;
  300.       end dr_fuzzy;
  301.  
  302.  
  303.     procedure dr_listing is
  304.       begin
  305.     if pred.r_arguments = null then
  306.       error(no_pointer,"LISTING requires one argument");
  307.       failed := true;
  308.     else
  309.       lookup(pred.r_arguments, level, bindings, value, value_level);
  310.       if value.is_a /= predicate then
  311.         error(no_pointer,"argument to LISTING must be a functor");
  312.       else
  313.         template.head.name := value.name;
  314.         temp := fetch_node(rule_base, template);
  315.         if temp /= null then
  316.           while temp /= null loop
  317.             print_clause(temp);
  318.             temp := temp.next;
  319.           end loop;
  320.           result := 1.0;
  321.         end if;
  322.       end if;
  323.     end if;
  324.       end dr_listing;
  325.  
  326.  
  327.     procedure dr_log is
  328.       begin
  329.     if (pred.r_arguments = null) or else
  330.        (pred.r_arguments.next_arg = null) then
  331.       error(no_pointer, "LN/LOG requires two arguments");
  332.       failed := true;
  333.     else
  334.       lookup(pred.r_arguments,level,bindings,value,value_level);
  335.       lookup(pred.r_arguments.next_arg,level,bindings,value2,value2_level);
  336.       if value.is_a = variable then
  337.         case value2.is_a is
  338.           when variable =>
  339.         error(no_pointer,"both arguments to LN/LOG uninstantiated");
  340.         failed := true;
  341.           when float_num =>
  342.         if pred.predicate = rw_ln then
  343.           a_template.fp_num := exp(value2.fp_num);
  344.         else -- rw_log
  345.           a_template.fp_num := 10.0 ** value2.fp_num;
  346.         end if;
  347.           when integer_num =>
  348.         if pred.predicate = rw_ln then
  349.           a_template.fp_num := exp(float(value2.int_num));
  350.         else -- rw_log
  351.           a_template.fp_num := 10.0 ** float(value2.int_num);
  352.         end if;
  353.           when others =>
  354.         error(no_pointer,"2nd argument to LN/LOG is an invalid type");
  355.         failed := true;
  356.           end case;
  357.         if not failed then
  358.           unify_arg(value,a_template,value_level,level,bindings,unified);
  359.           if unified then
  360.         result := 1.0;
  361.           else
  362.         raise prover_error;
  363.           end if;
  364.         end if;
  365.       elsif (value.is_a = float_num) or (value.is_a = integer_num) then
  366.         if value.is_a = float_num then
  367.           if pred.predicate = rw_ln then
  368.             a_template.fp_num := nat_log(value.fp_num);
  369.           else -- rw_log
  370.             a_template.fp_num := com_log(value.fp_num);
  371.           end if;
  372.         else -- integer_num
  373.           if pred.predicate = rw_ln then
  374.             a_template.fp_num := nat_log(float(value.int_num));
  375.           else -- rw_log
  376.             a_template.fp_num := com_log(float(value.int_num));
  377.           end if;
  378.         end if;
  379.         case value2.is_a is
  380.           when variable =>
  381.             unify_arg(value2,a_template,value2_level,level,bindings,unified);
  382.         if unified then
  383.           result := 1.0;
  384.         else
  385.           raise prover_error;
  386.         end if;
  387.           when float_num =>
  388.         if a_template.fp_num = value2.fp_num then
  389.           result := 1.0;
  390.         end if;
  391.           when integer_num =>
  392.         if a_template.fp_num = float(value2.int_num) then
  393.           result := 1.0;
  394.         end if;
  395.           when others =>
  396.         error(no_pointer,"2nd argument to LN/LOG is an invalid type");
  397.         failed := true;
  398.           end case;
  399.       else
  400.         error(no_pointer,"1st argument to LN/LOG is an invalid type");
  401.         failed := true;
  402.       end if;
  403.     end if;
  404.       end dr_log;
  405.  
  406.  
  407.     procedure dr_parse is
  408.       begin
  409.     file_ptr := pred.r_arguments;
  410.     while file_ptr /= null loop
  411.       if file_ptr.is_a = predicate then
  412.         put(file_ptr.name.name & ' ');
  413.         start_parser(file_ptr.name.name, (file_ptr.name.name & ".lst"));
  414.         parse_file(new_rules);
  415.         stop_parser;
  416.         put_line("contains:");
  417.         put(number_of_errors); put_line(" errors");
  418.         put(number_of_warnings); put_line(" warnings");
  419.         put(number_of_notes); put_line(" notes");
  420.         result := 1.0;
  421.       else
  422.         error(no_pointer, "invalid file name");
  423.         failed := true;
  424.       end if;
  425.       file_ptr := file_ptr.next_arg;
  426.     end loop;
  427.       end dr_parse;
  428.  
  429.  
  430.     procedure dr_put_tab is
  431.       begin
  432.     if pred.r_arguments = null then
  433.       error(no_pointer,(pred.name.name & " requires one argument"));
  434.       failed := true;
  435.     else
  436.       lookup(pred.r_arguments, level, bindings, value, value_level);
  437.       if (value.is_a /= integer_num) and (value.is_a /= float_num) then
  438.         if pred.predicate = rw_put then
  439.           error(no_pointer, "nonnumeric argument to PUT");
  440.         else
  441.           error(no_pointer, "nonnumeric argument to TAB");
  442.         end if;
  443.         failed := true;
  444.       else
  445.         if value.is_a = integer_num then
  446.           int_arg := value.int_num;
  447.         else -- fp
  448.           int_arg := integer(value.fp_num + 0.00001);
  449.         end if;
  450.         if pred.predicate = rw_put then
  451.           put(character'val(int_arg));
  452.         else
  453.           for i in 1..int_arg loop
  454.             put(' ');
  455.           end loop;
  456.         end if;
  457.         result := 1.0;
  458.       end if;
  459.     end if;
  460.       end dr_put_tab;
  461.  
  462.  
  463.     procedure dr_read is
  464.     eof : boolean;
  465.       begin
  466.     if pred.r_arguments = null then
  467.       error(no_pointer,"READ requires one argument");
  468.       failed := true;
  469.     else
  470.       lookup(pred.r_arguments, level, bindings, value, value_level);
  471.       start_parser("", "");
  472.       parse_read(read_value, eof);
  473.       stop_parser;
  474.       if (number_of_errors = 0) and (not eof) then
  475.         unify_arg(value, read_value, value_level, level, bindings, unified);
  476.         if unified then
  477.           result := 1.0;
  478.         end if;
  479.       else
  480.         failed := true;  -- errors have already been displayed to screen
  481.       end if;
  482.     end if;
  483.       end dr_read;
  484.  
  485.  
  486.     procedure dr_reset is
  487.       begin
  488.     release(rule_base);
  489.     rule_base := init_tree;
  490.     put_line("rule base reinitialized");
  491.     result := 1.0;
  492.       end dr_reset;
  493.  
  494.  
  495.     procedure dr_retract is
  496.       begin
  497.     --
  498.     --  This retract logic has one inherent, insidious bug.  Clauses which
  499.     --  have been retracted from the rule base may still be pointed to by
  500.     --  db_ptr in various instantiations of Seek already on the call stack.
  501.     --  There appears to be no way to fix this without major program
  502.     --  restructuring.  This problem should not arise too often, but
  503.     --  in hopes of mitigating potential damages RETRACT does not
  504.     --  deallocate retracted rules.
  505.     --
  506.     if pred.r_arguments = null then
  507.       error(no_pointer,"RETRACT requires one argument");
  508.       failed := true;
  509.     else
  510.       lookup(pred.r_arguments, level, bindings, value, value_level);
  511.       if value.is_a /= predicate then
  512.         error(no_pointer,"argument to RETRACT must be a functor");
  513.         failed := true;
  514.       else
  515.         template.head.name := value.name;
  516.         template.head.p_arguments := value.p_arguments;
  517.         temp := fetch_node(rule_base, template);
  518.         unified := false;
  519.         while temp /= null loop
  520.           temp_bindings := bindings;
  521.           unify(template.head, temp.head, value_level, integer'last,
  522.             temp_bindings, unified);
  523.           if unified then
  524.         bindings := temp_bindings;
  525.         exit;
  526.           else
  527.             release(temp_bindings, bindings); -- the bindings aren't valid
  528.           end if;
  529.           temp_bindings := bindings;
  530.           temp := temp.next;
  531.         end loop;
  532.         if unified then
  533.           if temp.prev = null then -- the first node, so must update
  534.         if temp.next = null then
  535.           delete_node(rule_base, temp, not_found);
  536.         else
  537.           temp.next.prev := null;
  538.           temp := temp.next;
  539.           update_node(rule_base, temp, not_found);
  540.         end if;
  541.         if not_found then
  542.           raise prover_error;
  543.         end if;
  544.           else
  545.         temp.prev.next := temp.next;
  546.         if temp.next /= null then
  547.           temp.next.prev := temp.prev;
  548.         end if;
  549.           end if;
  550.           result := 1.0;
  551.         else
  552.           failed := true;
  553.         end if;
  554.       end if;
  555.     end if;
  556.       end dr_retract;
  557.  
  558.  
  559.     procedure dr_threshold is
  560.       begin
  561.     if pred.r_arguments = null then
  562.       error(no_pointer,"THRESHOLD requires one argument");
  563.       failed := true;
  564.     else
  565.       lookup(pred.r_arguments, level, bindings, value, value_level);
  566.           if value.is_a = variable then -- set variable to current threshold
  567.         unify_arg(value, new argument'(float_num, null, threshold),
  568.               value_level, level, bindings, unified);
  569.           result := 1.0;
  570.         if not unified then
  571.           raise prover_error;
  572.         end if;
  573.           elsif value.is_a = float_num then -- set the search threshold
  574.             threshold := value.fp_num;
  575.             result_node := new AST'(threshold_marker, 1.0, threshold);
  576.         current_truth := 1.0;  -- must complete our result here
  577.         result_done := true;
  578.       else
  579.         error(no_pointer, "invalid argument to THRESHOLD");
  580.         failed := true;
  581.           end if;
  582.     end if;
  583.       end dr_threshold;
  584.  
  585.  
  586.     procedure dr_trace is
  587.       begin
  588.     if  pred.predicate = rw_trace then
  589.       trace(true);
  590.     else -- rw_notrace
  591.       trace(false);
  592.     end if;
  593.     result := 1.0;
  594.       end dr_trace;
  595.  
  596.  
  597.     procedure dr_types is
  598.       begin
  599.     lookup(pred.r_arguments, level, bindings, value, value_level);
  600.     result := 0.0;
  601.     case value.is_a is
  602.       when integer_num =>
  603.         if (pred.predicate = rw_integer) or
  604.            (pred.predicate = rw_number) or
  605.            (pred.predicate = rw_atomic) or
  606.            (pred.predicate = rw_nonvar) then
  607.           result := 1.0;
  608.         end if;
  609.       when float_num =>
  610.         if (pred.predicate = rw_float) or
  611.            (pred.predicate = rw_number) or
  612.            (pred.predicate = rw_atomic) or
  613.            (pred.predicate = rw_nonvar) then
  614.           result := 1.0;
  615.         end if;
  616.       when character_lit =>
  617.         if (pred.predicate = rw_atomic) or
  618.            (pred.predicate = rw_nonvar) then
  619.           result := 1.0;
  620.         end if;
  621.       when predicate =>
  622.         if (pred.predicate = rw_atom) or
  623.            (pred.predicate = rw_atomic) or
  624.            (pred.predicate = rw_nonvar) then
  625.           result := 1.0;
  626.         end if;
  627.       when prolog_list =>
  628.         if (pred.predicate = rw_nonvar) then
  629.           result := 1.0;
  630.         end if;
  631.       when variable =>
  632.         if (pred.predicate = rw_var) then
  633.           result := 1.0;
  634.         end if;
  635.     end case;
  636.     if result = 0.0 then
  637.       failed := true;
  638.     end if;
  639.       end dr_types;
  640.  
  641.  
  642.   begin -- do_reserved
  643.  
  644.     --
  645.     --  Call the proper routine for this reserved word.  A few very simple
  646.     --  cases are handled within this procedure (for example "cut").
  647.     --
  648.     case pred.predicate is
  649.       when cut => result := 1.0;  -- "cut" logic really appears in Seek
  650.       when rw_asserta | rw_assertz => dr_assert;
  651.       when rw_call => dr_call;
  652.       when rw_consult =>  dr_consult;
  653.       when rw_fail => failed := true;
  654.       when rw_fuzzy => dr_fuzzy;
  655.       when rw_listing => dr_listing;
  656.       when rw_ln | rw_log => dr_log;
  657.       when rw_nl => new_line;
  658.             result := 1.0;
  659.       when rw_parse => dr_parse;
  660.       when rw_put | rw_tab => dr_put_tab;
  661.       when rw_read => dr_read;
  662.       when rw_repeat => result := 1.0;  -- real logic appears in Seek
  663.       when rw_reset => dr_reset;
  664.       when rw_retract => dr_retract;
  665.       when rw_threshold => dr_threshold;
  666.       when rw_trace | rw_notrace => dr_trace;
  667.       when rw_true => result := 1.0;
  668.       when rw_var | rw_nonvar | rw_atom |
  669.        rw_atomic | rw_number | rw_integer | rw_float => dr_types;
  670.       when rw_write =>
  671.     print_argument(pred.r_arguments, bindings, level, no_quote);
  672.     result := 1.0;
  673.       when others => put(pred.predicate); new_line;
  674.     error(no_pointer, "reserved predicate not implemented");
  675.     failed := true;
  676.     end case;
  677.     if not result_done then
  678.       current_truth := result;
  679.       result_node := new AST'(fuzzy_value, result);
  680.     end if;
  681.  
  682.   exception
  683.     when name_error => -- this happens in consult, parse, and reconsult
  684.       failed := true;
  685.       put_line("not found--predicate aborted at this point");
  686.  
  687.   end do_reserved;
  688.